/**
 * 游戏专属的Http请求工具
 */

import Http, { HttpRequestOptions, HttpResponse, HttpResponseCallback } from "./Http";

interface GameHttpRequestOption extends HttpRequestOptions {
    noCallback?: boolean;   // 是否屏蔽 _beforeRequest 和 _afterResponse
}

export default class GameHttp extends Http {
    private static _baseURL: string;
    // 玩家token，用于验证数据以防止请求伪造
    private static _token?: string;
    // 请求前回调，可以在这里打开等待
    private static _beforeRequest: Function;
    // 响应后回调，可以在这里关闭等待
    private static _afterResponse: HttpResponseCallback;

    public static BaseURL(baseURL: string) {
        this._baseURL = baseURL;
    }

    public static Token(token: string) {
        this._token = token;
    }

    public static BeforeRequest(beforeRequest: Function) {
        this._beforeRequest = beforeRequest;
    }

    public static AfterResponse(afterResponse: HttpResponseCallback) {
        this._afterResponse = afterResponse;
    }

    /**
     * HTTP请求
     * @param method 请求方法
     * @param url 请求地址，可以是完整的URL，也可以再设置了baseURL后为uri: "/api/user/list"
     * @param params 请求参数
     * @param callback 结果回调
     * @param options 其他选项
     */
    public static _Request(method: string, url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption): void {
        if (typeof url == "string") {
            url = new URL(url, this._baseURL);
        }

        if (this._token) {
            params["_token"] = this._token;
        }

        if (!options.noCallback) {
            this._beforeRequest && this._beforeRequest();
            if (this._afterResponse) {
                const _callback: HttpResponseCallback = callback;
                callback = (response: HttpResponse): void => {
                    _callback && _callback(response);
                    this._afterResponse(response);
                }
            }
        }

        super[method](url, params, callback, options);
    }

    public static Get(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
        this._Request("Get", url, params, callback, options);
    }

    public static Post(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
        this._Request("Post", url, params, callback, options);
    }

    public static Patch(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
        this._Request("Patch", url, params, callback, options);
    }

    public static Put(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
        this._Request("Put", url, params, callback, options);
    }

    public static Delete(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
        this._Request("Delete", url, params, callback, options);
    }
}

export function gamehttp_get(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
    return GameHttp.Get(url, params, callback, options);
}

export function gamehttp_post(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
    return GameHttp.Post(url, params, callback, options);
}

export function gamehttp_patch(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
    return GameHttp.Patch(url, params, callback, options);
}

export function gamehttp_put(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
    return GameHttp.Put(url, params, callback, options);
}

export function gamehttp_delete(url: string | URL, params?: object, callback?: HttpResponseCallback, options?: GameHttpRequestOption) {
    return GameHttp.Delete(url, params, callback, options);
}